package cn.chenchendemospringboot.order_demo.service.impl;

import cn.chenchendemospringboot.order_demo.entity.Inventory;
import cn.chenchendemospringboot.order_demo.entity.Order;
import cn.chenchendemospringboot.order_demo.mapper.OrderMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> {

    @Autowired
    private RestTemplate restTemplate;

    public boolean saveOrder(Order order) {

        Inventory inventory = new Inventory();

        boolean result = save(order);
//        int i = 1/0;
        if(result){
            ResponseEntity<?> response = restTemplate.postForEntity("http://localhost:8090/demo/inventory/insert", inventory, String.class);

        }
    return true;
    }

    /**
     * 分布式事务测试：
     * 针对这段代码 我提出一个问题 调用库存失败  本地事务也回滚了，所以本地事务就实现了 不需要分布式事务了，老师给我的回答：假设，远程超时了，你怎么确定我成功了，我本地事务是否回滚？没太听懂老师的回答，可以解释一下吗
     *
     * 你的老师提出的问题实际上是在指出分布式事务中的一个常见问题：在调用远程服务时，如果发生超时，你无法立即确定远程服务是否真的失败了，或者它是否实际上已经成功执行了操作。以下是详细解释：
     *
     * 超时并不总是意味着失败：
     * 当远程服务调用超时时，这可能意味着请求没有在预定的时间内得到响应。但这并不一定意味着远程服务没有处理请求。网络问题、服务延迟或其他中间件问题可能导致超时，即使远程服务实际上已经成功处理了请求。
     * 本地事务回滚的决策：
     * 在你的代码中，如果restTemplate.postForEntity调用超时，它将抛出一个异常。由于saveOrder方法上使用了@Transactional注解，Spring将捕获这个异常并回滚本地事务。这意味着即使远程服务可能已经成功处理了请求，本地事务（包括订单保存）也会被撤销。
     * 分布式事务的一致性问题：
     * 在分布式系统中，仅仅回滚本地事务可能不足以保证整个系统的一致性。例如，如果远程服务实际上已经减少了库存，但本地事务回滚了，系统就处于不一致的状态：订单没有被创建，但库存已经被减少了。
     * 老师的回答是在强调，如果你在超时后简单地回滚本地事务，你可能会错误地处理了这种情况。以下是老师回答的解释：
     *
     * “假设，远程超时了，你怎么确定我成功了”：
     * 这是在问，当远程服务调用超时时，你如何知道远程服务是否真的执行了操作。如果你不能确定，那么简单地回滚本地事务可能会导致错误的决定。
     * “我本地事务是否回滚？”：
     * 这是在问，在不确定远程服务调用结果的情况下，你是否应该回滚本地事务。如果你的本地事务回滚了，但远程服务实际上已经成功执行了操作，那么你将需要额外的逻辑来处理这种不一致性。
     * 为了解决这个问题，你可能需要实现以下策略之一：
     *
     * 重试机制：在超时后，可以尝试重新发送请求到远程服务，以确认操作是否成功。
     * 幂等性：确保远程服务可以安全地处理重复请求，这样即使你重试请求，也不会产生副作用。
     * 补偿事务：如果最终确定远程服务失败了，可以执行补偿事务来撤销远程服务可能已经执行的操作。
     * 在分布式系统中，保证跨服务操作的一致性通常需要更复杂的解决方案，如分布式事务管理器（例如Seata、Atomikos）或使用SAGA模式等。
     */
}
